<template>
  <div class="component__rich-text needsclick">
    <no-ssr>
      <div
        ref="myTextEditor"
        :value="content"
        @change="onEditorChange($event)"
        v-quill:myQuillEditor="editorOption"
      ></div>
    </no-ssr>
    <Modal
      width="450px"
      id="file_upload"
      :title="
        uploadType == 0
          ? '视频上传'
          : uploadType == 1
          ? '音频上传'
          : uploadType == 2
          ? '图片上传'
          : ''
      "
      v-model="is_show_upload"
      ok-text="确定"
      cancel-text="取消"
      @on-cancel="handleClose"
      @on-ok="addVideoLink"
    >
      <Tabs v-model="activeName">
        <TabPane
          :label="
            uploadType == 0
              ? '视频上传'
              : uploadType == 1
              ? '音频上传'
              : uploadType == 2
              ? '图片上传'
              : ''
          "
          name="first"
        >
          <Upload
            class="avatar-uploader"
            ref="avatar-uploader"
            action="/api/common/richtext/file-upload"
            :show-file-list="false"
            :auto-upload="false"
            :show-upload-list="false"
            :before-upload="beforeUpload"
            :on-success="unloadSuccess"
            :on-cancel="handleClose"
            :headers="{
              authorization: token
            }"
          >
            <template v-if="[0].includes(uploadType) && dialogData.file">
              <video v-if="dialogData.file" class="video-box" controls>
                <source :src="dialogData.file" type="video/mp4" />
              </video>
            </template>
            <template v-if="[1].includes(uploadType) && dialogData.file">
              <audio controls>
                <source :src="dialogData.file" type="audio/mpeg" />
              </audio>
            </template>
            <template v-if="[2].includes(uploadType) && dialogData.file">
              <img :src="dialogData.file" />
            </template>
            <i
              v-if="!dialogData.file"
              class="ivu-icon ivu-icon-ios-add upload-icon"
            ></i>
          </Upload>
          <!-- <Button
            class="btn-submit"
            type="primary"
            @click="addVideoLink('file')"
            >添加</Button
          > -->
        </TabPane>
        <TabPane
          :label="
            uploadType == 0
              ? '视频链接'
              : uploadType == 1
              ? '音频链接'
              : uploadType == 2
              ? '图片链接'
              : ''
          "
          name="second"
        >
          <Input
            v-model="dialogData.link"
            :placeholder="
              '请输入' +
                (uploadType == 0
                  ? '视频链接'
                  : uploadType == 1
                  ? '音频链接'
                  : uploadType == 2
                  ? '图片链接'
                  : '')
            "
          ></Input>
          <!-- <Button
            class="btn-submit"
            type="primary"
            @click="addVideoLink('link')"
            >添加</Button
          > -->
        </TabPane>
      </Tabs>

      <div class="loading" v-if="is_loading">
        <van-loading :color="web_info.THEME_COLOR" vertical>
          <!-- <span style="color:#fff">{{ $t("locale.layouts.default.t1") }}</span> -->
        </van-loading>
      </div>
    </Modal>
    <div class="disabled" v-if="disabled"></div>
  </div>
</template>

<script>
import quillConfig from "./quill-config.js";
import { fileToBase64, dataURLtoFile } from "~/utils/file";
import { richTextAssetsUpload } from "~/api/index";
import { mapState } from "vuex";

if (process.client) {
  const Quill = require("vue-quill-editor").Quill;
  let Link = Quill.import("formats/link");
  let BlockEmbed = Quill.import("blots/block/embed");
  class AudioBlot extends BlockEmbed {
    static create(value) {
      let all_audio_node = document.querySelectorAll("audio");
      let _id = all_audio_node.length;
      let node = super.create(value);
      node.setAttribute("src", this.sanitize(value)); //设置audio的src属性
      node.setAttribute("controls", true); //设置audio的controls，否则他将不会显示
      node.setAttribute("controlsList", "nodownload"); //设置audio的下载功能为不能下载
      node.setAttribute("id", "audio" + _id); //设置一个id
      return node;
    }
    static sanitize(url) {
      return Link.sanitize(url); // eslint-disable-line import/no-named-as-default-member
    }
    static value(domNode) {
      return domNode.getAttribute("src");
    }
  }
  AudioBlot.blotName = "audio";
  AudioBlot.tagName = "audio"; //自定义的标签为audio
  Quill.register(AudioBlot, true);

  class VideoBlot extends BlockEmbed {
    static create(value) {
      const node = super.create(value);
      // 添加video标签所需的属性
      node.setAttribute("controls", "controls");
      node.setAttribute("type", "video/mp4");
      node.setAttribute("src", this.sanitize(value));
      return node;
    }
    static sanitize(url) {
      return Link.sanitize(url); // eslint-disable-line import/no-named-as-default-member
    }
    static value(domNode) {
      return domNode.getAttribute("src");
    }
    html() {
      const { video } = this.value();
      return `<a href="${video}">${video}</a>`;
    }
  }
  VideoBlot.blotName = "video"; // 这里不用改，楼主不用iframe，直接替换掉原来，如果需要也可以保留原来的，这里用个新的blot
  VideoBlot.className = "ql-video";
  VideoBlot.tagName = "video"; // 用video标签替换iframe
  Quill.register(VideoBlot, true);
}

export default {
  props: ["content", "disabled"],
  data() {
    return {
      is_show_upload: false, //上传对话框
      is_loading: false,
      dialogData: {
        file: "",
        link: ""
      },
      uploadType: 0, //0:视频,1:音频,2:图片
      activeName: "first"
    };
  },
  computed: {
    ...mapState({
      user_info(state) {
        return state.user_info;
      },
      web_info(state) {
        return state.web_info;
      },
      token(state) {
        return state.token;
      }
    }),
    editorOption() {
      return {
        modules: {
          toolbar: {
            // 如果不上传图片到服务器，此处不必配置
            container: [
              ["bold", "italic", "underline", "strike"],
              ["blockquote", "code-block"],
              // [{ header: 1 }, { header: 2 }],
              [{ list: "ordered" }, { list: "bullet" }],
              // [{ script: 'sub' }, { script: 'super' }],
              [{ indent: "-1" }, { indent: "+1" }],
              // [{ direction: 'rtl' }],
              // [{ size: ['small', false, 'large', 'huge'] }],
              [{ header: [1, 2, 3, 4, 5, 6, false] }],
              [{ color: [] }, { background: [] }],
              // [{ font: [] }],
              [{ align: [] }],
              // ['clean'],
              ["link", "video", "image", "audio"]
            ], // container为工具栏，可自行配置
            handlers: {
              video: val => {
                this.uploadType = 0;
                if (this.disabled) {
                  return false;
                }
                this.is_show_upload = true;
              },
              audio: val => {
                this.uploadType = 1;
                if (this.disabled) {
                  return false;
                }
                this.is_show_upload = true;
              },
              image: val => {
                this.uploadType = 2;
                if (this.disabled) {
                  return false;
                }
                this.is_show_upload = true;
              }
            }
          }
        },
        uploadConfig: {
          token: this.$store.state.token,
          action: "/api/common/richtext/file-upload"
        },
        placeholder: "请输入内容",
        initAudioButton() {
          const voiceButtons = document.querySelectorAll(".ql-audio");
          if (Array.from(voiceButtons).length > 0) {
            Array.from(voiceButtons).forEach((item, index) => {
              item && item.classList && item.classList.add("ivu-icon");
              item && item.classList && item.classList.add("ivu-icon-ios-mic");
            });
          }
        }
      };
    }
  },
  watch: {},
  methods: {
    handlePicAction(file) {
      fileToBase64(file.raw, res => {
        if (file == "remove") {
          let _copy_obj = {
            ...this.dialogData,
            file: undefined
          };
          this.dialogData = _copy_obj;
          this.$refs["logo-uploader"].clearFiles();
        } else {
          this.dialogData = {
            ...this.dialogData,
            file: res
          };
        }
      });
    },
    beforeUpload(file) {
      console.log("file:", file);
      if (this.uploadType == 0) {
        if (["video/mp4", "video/ogg", "video/webm"].includes(file.type)) {
          this.is_loading = true;
          return true;
        } else {
          this.$Message.error("仅支持mp4、ogg、webm格式的视频");
          return false;
        }
      } else if (this.uploadType == 1) {
        if (["audio/mpeg", "audio/wav", "audio/ogg"].includes(file.type)) {
          this.is_loading = true;
          return true;
        } else {
          this.$Message.error("仅支持mp3、wav、ogg格式的音频");
          return false;
        }
      } else if (this.uploadType == 2) {
        if (
          ["image/jpeg", "image/jpg", "image/png", "image/gif"].includes(
            file.type
          )
        ) {
          this.is_loading = true;
          return true;
        } else {
          this.$Message.error("仅支持jpeg、jpg、png、gif格式的图片");
          return false;
        }
      }
    },
    unloadSuccess(res) {
      if (res.code == 200) {
        this.is_loading = false;
        this.dialogData = {
          ...this.dialogData,
          file: res.data
        };
      }
      console.log("res:", res);
    },
    async addVideoLink(type) {
      //插入在富文本中的位置
      let index = 0;
      let range;
      try {
        range = this.$refs.myTextEditor["__quill"].selection.savedRange.index;
        index = range;
      } catch (e) {}

      if (this.uploadType == 0) {
        if (type == "link" || this.activeName == "second") {
          this.is_show_upload = false;
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "video",
            this.dialogData.link + "?isView=1"
          );
          this.$refs.myTextEditor["__quill"].setSelection(index + 1);
        } else if (type == "file" || this.activeName == "first") {
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "video",
            this.dialogData.file + "?isView=1"
          );
          this.$refs.myTextEditor["__quill"].setSelection(index + 1);
          this.is_show_upload = false;
        }
        this.handleClose();
      } else if (this.uploadType == 1) {
        if (type == "link" || this.activeName == "second") {
          this.is_show_upload = false;
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "audio",
            this.dialogData.link + "?isView=1"
          );
        } else if (type == "file" || this.activeName == "first") {
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "audio",
            this.dialogData.file + "?isView=1",
            "api"
          );
          this.$refs.myTextEditor["__quill"].setSelection(index + 1); //光标位置向后移动一位
          this.is_show_upload = false;
        }
        this.handleClose();
      } else if (this.uploadType == 2) {
        if (type == "link" || this.activeName == "second") {
          this.is_show_upload = false;
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "image",
            this.dialogData.link
          );
        } else if (type == "file" || this.activeName == "first") {
          this.$refs.myTextEditor["__quill"].insertEmbed(
            index,
            "image",
            this.dialogData.file + "?isView=1"
          );
          this.$refs.myTextEditor["__quill"].setSelection(index + 1); //光标位置向后移动一位
          this.is_show_upload = false;
        }
        this.handleClose();
      }
    },
    handleClose() {
      this.dialogData = {
        file: "",
        link: ""
      };
      this.activeName = "first";
    },
    handleSuccess(res, file, fileList) {
      this.fullscreenLoading = false;
      // 获取富文本组件实例
      let quill = this.$refs.myTextEditor["__quill"];
      if (res.code === 0) {
        // 如果上传成功
        let length = quill.getSelection().index; // 获取光标所在位置
      } else {
        this.$message.error(res.msg); // 上传失败，提示错误信息
      }
    },
    onEditorChange(e) {
      this.$emit("handleChange", e.html);
    }
  },
  created() {},
  mounted() {
    this.$nextTick(() => {
      this.editorOption.initAudioButton(); //初始化音频图标，这样才能显示
    });
  }
};
</script>

<style lang="scss">
#file_upload {
  z-index: 999;
  position: relative;
  overflow: hidden;
  .upload-icon {
    font-size: 28px;
    color: #8c939d;
    width: 150px;
    height: 150px;
    line-height: 150px;
    text-align: center;
  }
  .avatar-uploader {
    text-align: center;
  }
  .btn-submit {
    margin-top: 15px;
  }
  .loading {
    z-index: 99;
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background-color: rgba(255, 255, 255, 0.6);
    overflow: hidden;
    .loading-icon {
    }
  }
}
.component__rich-text {
  position: relative;
  @import "assets/css/richtext.scss";
  .ql-container {
    min-height: 255px;
  }
  .avatar-uploader {
    .el-upload {
      margin: 0 auto 15px;
      display: block;
      width: 260px;
      height: 150px;
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
    }
    .el-upload:hover {
      border-color: #409eff;
    }
    .avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 150px;
      height: 150px;
      line-height: 150px;
      text-align: center;
    }
  }
  .el-dialog__body {
    padding: 0 20px 20px 20px;
  }
  .btn-submit {
    margin-top: 12px;
  }
  .video-box {
    width: 100%;
    height: auto;
  }
  .ql-editor {
    audio {
      width: 100%;
      height: 25px;
    }
  }
  .disabled {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 9;
    width: 100%;
    height: 100%;
    cursor: not-allowed;
  }
}
</style>
